import {
  Injectable,
  ConflictException,
  NotFoundException,
  BadRequestException,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User, UserStatus, UserGender } from './entities/user.entity';
import {
  UserSocialAuth,
  SocialProvider,
} from './entities/user-social-auth.entity';
import { RegisterDto } from './dto/register.dto';
import { UpdateUserDto, UpdatePasswordDto } from './dto/update-user.dto';
import { PasswordUtil } from '../../common/utils/password.util';

@Injectable()
export class UserService {
  constructor(
    @InjectRepository(User)
    private userRepository: Repository<User>,
    @InjectRepository(UserSocialAuth)
    private socialAuthRepository: Repository<UserSocialAuth>,
  ) {}

  /**
   * 创建用户（注册）
   */
  async create(registerDto: RegisterDto): Promise<User> {
    const { username, password, confirmPassword, ...userInfo } = registerDto;

    // 检查密码确认
    if (password !== confirmPassword) {
      throw new BadRequestException('两次输入的密码不一致');
    }

    // 检查用户名是否已存在
    const existingUser = await this.userRepository.findOne({
      where: [
        { username },
        { email: userInfo.email },
        { phone: userInfo.phone },
      ],
    });

    if (existingUser) {
      if (existingUser.username === username) {
        throw new ConflictException('用户名已存在');
      }
      if (existingUser.email === userInfo.email) {
        throw new ConflictException('邮箱已被注册');
      }
      if (existingUser.phone === userInfo.phone) {
        throw new ConflictException('手机号已被注册');
      }
    }

    // 创建新用户
    const user = new User();
    user.username = username;
    user.nickname = userInfo.nickname || username;
    user.email = userInfo.email || null;
    user.phone = userInfo.phone || null;
    user.passwordHash = await PasswordUtil.hash(password);
    user.gender = UserGender.UNKNOWN;
    user.status = UserStatus.ACTIVE;

    return this.userRepository.save(user);
  }

  /**
   * 根据用户名查找用户
   */
  async findByUsername(username: string): Promise<User | null> {
    return this.userRepository.findOne({
      where: [{ username }, { email: username }, { phone: username }],
    });
  }

  /**
   * 根据ID查找用户
   */
  async findById(id: number): Promise<User | null> {
    return this.userRepository.findOne({
      where: { id, status: UserStatus.ACTIVE },
    });
  }

  /**
   * 更新用户信息
   */
  async update(id: number, updateUserDto: UpdateUserDto): Promise<User> {
    const user = await this.findById(id);
    if (!user) {
      throw new NotFoundException('用户不存在');
    }

    // 检查邮箱和手机号是否已被其他用户使用
    if (updateUserDto.email || updateUserDto.phone) {
      const existingUser = await this.userRepository.findOne({
        where: [{ email: updateUserDto.email }, { phone: updateUserDto.phone }],
      });

      if (existingUser && existingUser.id !== id) {
        if (existingUser.email === updateUserDto.email) {
          throw new ConflictException('邮箱已被其他用户使用');
        }
        if (existingUser.phone === updateUserDto.phone) {
          throw new ConflictException('手机号已被其他用户使用');
        }
      }
    }

    // 更新用户信息
    Object.assign(user, updateUserDto);
    return this.userRepository.save(user);
  }

  /**
   * 修改密码
   */
  async updatePassword(
    id: number,
    updatePasswordDto: UpdatePasswordDto,
  ): Promise<void> {
    const user = await this.findById(id);
    if (!user) {
      throw new NotFoundException('用户不存在');
    }

    const { oldPassword, newPassword, confirmPassword } = updatePasswordDto;

    // 检查新密码确认
    if (newPassword !== confirmPassword) {
      throw new BadRequestException('两次输入的新密码不一致');
    }

    // 验证旧密码
    const isOldPasswordValid = await PasswordUtil.verify(
      oldPassword,
      user.passwordHash,
    );
    if (!isOldPasswordValid) {
      throw new BadRequestException('旧密码不正确');
    }

    // 更新密码
    user.passwordHash = await PasswordUtil.hash(newPassword);
    await this.userRepository.save(user);
  }

  /**
   * 更新最后登录时间
   */
  async updateLastLoginTime(id: number): Promise<void> {
    await this.userRepository.update(id, {
      lastLoginTime: new Date(),
    });
  }

  /**
   * 创建或更新第三方登录信息
   */
  async createOrUpdateSocialAuth(
    userId: number,
    provider: SocialProvider,
    openId: string,
    unionId?: string,
  ): Promise<UserSocialAuth> {
    let socialAuth = await this.socialAuthRepository.findOne({
      where: { provider, openId },
    });

    if (socialAuth) {
      // 更新现有记录
      socialAuth.userId = userId;
      if (unionId) socialAuth.unionId = unionId;
      return this.socialAuthRepository.save(socialAuth);
    } else {
      // 创建新记录
      socialAuth = new UserSocialAuth();
      socialAuth.userId = userId;
      socialAuth.provider = provider;
      socialAuth.openId = openId;
      if (unionId) socialAuth.unionId = unionId;
      return this.socialAuthRepository.save(socialAuth);
    }
  }

  /**
   * 根据第三方信息查找用户
   */
  async findBySocialAuth(
    provider: SocialProvider,
    openId: string,
  ): Promise<User | null> {
    const socialAuth = await this.socialAuthRepository.findOne({
      where: { provider, openId },
      relations: ['user'],
    });

    return socialAuth?.user || null;
  }

  /**
   * 禁用用户
   */
  async disableUser(id: number): Promise<void> {
    await this.userRepository.update(id, { status: UserStatus.DISABLED });
  }

  /**
   * 启用用户
   */
  async enableUser(id: number): Promise<void> {
    await this.userRepository.update(id, { status: UserStatus.ACTIVE });
  }
}
